package services

import models.{KeyValue, KeyValueRepository}
import play.api.Logging
import play.api.cache.SyncCacheApi
import play.api.libs.json.{JsValue, Json}
import services.kingdee.{AuthUser, CookieDict}

import javax.inject.{Inject, Singleton}
import scala.concurrent.duration._
import scala.concurrent.{Await, ExecutionContext}

@Singleton
class KeyValueService @Inject()(
                                 kvRepo: KeyValueRepository,
                                 cache: SyncCacheApi
                               )(implicit ec: ExecutionContext)
  extends Logging {
  val sec = security.Encode
  val hmacMassage = "hashlib.sha224((value+str(timestamp)).encode(encoding='UTF-8')).hexdigest()"
  val zeroTime = 1_600_101_725L // System.currentTimeMillis() / 997

  def loginAuth(authUser: AuthUser) = {
    val response_loginFalse = Json.parse("""{"Message":"用户名或密码错误！","MessageCode":"002005030013414","LoginResultType":0,"AccessToken":null,"KdAccessResult":null,"IsSuccessByAPI":false}""")
    val response_loginTrue = Json.obj("Message" -> None, "MessageCode" -> "CheckPasswordPolicy", "LoginResultType" -> 1, "AccessToken" -> None, "KdAccessResult" -> None, "IsSuccessByAPI" -> true)
    val response_noUser = Json.obj("Message" -> "用户名不存在！", "MessageCode" -> "002005030013414", "LoginResultType" -> 0, "AccessToken" -> None, "KdAccessResult" -> None, "IsSuccessByAPI" -> false)
    val key = authUser.acctID + "@" + authUser.userName
    val value = sec.hashSHA256("kdservice-sessionid" + authUser.userName + "@" + authUser.password)
    logger.debug(s"loginAuth(authUser: AuthUser) key=$key, value = $value")
    val kv = cache.getOrElseUpdate[KeyValue](key, 1.hours) {
      val r = Await.result(kvRepo.findByKey(key), Duration.Inf)
      if (r.isEmpty) new KeyValue else r.head
    }
    logger.debug(s"kv = ${kv.toString}")
    if (value == kv.vValue && kv.vTimestamp > 0) {
      val nowMilliusTime: Long = System.currentTimeMillis()
      val aspkey = java.util.UUID.nameUUIDFromBytes(key.getBytes).toString
      val kdSessionid = sec.hmacSHA256(nowMilliusTime.toString, aspkey)
      logger.debug(s"loginAuth(authUser: AuthUser) aspkey=$aspkey, kdSessionid = $kdSessionid")
      cache.getOrElseUpdate[CookieDict](aspkey, 10.minutes) {
        CookieDict(aspSession = aspkey, kdSessionid = kdSessionid, messages = response_loginTrue)
      }
    }
    else CookieDict(messages = response_noUser)
  }

  def validateUser(cookieDict: CookieDict): Boolean = {
    val cookie = cache.get[CookieDict](cookieDict.aspSession).getOrElse(new CookieDict)
    cookie.kdSessionid.equals(cookieDict.kdSessionid)
  }

}
